package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysModule;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysModuleMapper;
import com.ruoyi.system.service.ISysModuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.ruoyi.common.constant.CacheConstants.DEFAULT_MODULE_KEY;

@Slf4j
@Service
public class SysModuleServiceImpl implements ISysModuleService {

    @Autowired
    private SysModuleMapper sysModuleMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 根据表名查询功能模块（默认权限）
     * @param tableName 表名
     * @return 功能模块
     */
    @Override
    public SysModule getModuleByTableName(String tableName) {
        return sysModuleMapper.selectModuleByTableName(tableName);
    }

    /**
     * 根据表名和角色ID查询功能模块权限配置
     * @param tableName 表名
     * @param roleIds 角色ID列表
     * @return 功能模块列表
     */
    @Override
    public List<SysModule> getModuleByTableNameAndRoleIds(String tableName, List<Long> roleIds) {
        return sysModuleMapper.selectModuleByTableNameAndRoleIds(tableName, roleIds);
    }

    /**
     * 分页查询功能模块列表
     * @param page 分页信息
     * @param module 功能模块查询条件
     * @return 功能模块列表
     */
    @Override
    public IPage<SysModule> selectModuleList(IPage<SysModule> page, SysModule module) {
        IPage<SysModule> moduleList = sysModuleMapper.selectModuleList(page, module);
        List<SysModule> modules = moduleList.getRecords();
        storeDefaultModuleToRedis(modules);
        return moduleList;
    }

    private void storeDefaultModuleToRedis(List<SysModule> modules) {
        // 将默认权限的表名写入Redis Set
        if (redisCache != null && modules != null) {
            Set<String> tableNames = new HashSet<>();
            for (SysModule m : modules) {
                if (m.getRoleId() == 0) {
                    tableNames.add(m.getTableName());
                }
            }
            redisCache.setCacheSet(DEFAULT_MODULE_KEY, tableNames);
        }
    }

    /**
     * 根据ID查询功能模块详情
     * @param moduleId 功能模块ID
     * @return 功能模块详情
     */
    @Override
    public SysModule selectModuleById(Long moduleId) {
        return sysModuleMapper.selectModuleById(moduleId);
    }

    /**
     * 新增功能模块
     * @param module 功能模块
     * @return 新增结果
     */
    @Override
    public int insertModule(SysModule module) {
        if (module.getRoleId() == 0) {
            Set<String> tableNames = new HashSet<>();
            tableNames.add(module.getTableName());
            redisCache.setCacheSet(DEFAULT_MODULE_KEY, tableNames);
        }
        return sysModuleMapper.insertModule(module);
    }

    /**
     * 修改功能模块
     * @param module 功能模块
     * @return 修改结果
     */
    @Override
    public int updateModule(SysModule module) {
        return sysModuleMapper.updateModule(module);
    }

    /**
     * 删除功能模块
     * @param moduleIds 功能模块ID数组
     * @return 删除结果
     */
    @Override
    public int deleteModuleByIds(Long[] moduleIds) {
        for (Long moduleId : moduleIds) {
            deleteDefaultModuleCache(moduleId);
        }
        return sysModuleMapper.deleteModuleByIds(moduleIds);
    }

    private void deleteDefaultModuleCache(Long moduleId) {
        SysModule sysModule = sysModuleMapper.selectModuleById(moduleId);
        SysModule defaultModule = sysModuleMapper.getDefaultModuleByModuleName(sysModule.getModuleName());
        if (defaultModule != null) {
            redisCache.deleteCacheSetValue(DEFAULT_MODULE_KEY, defaultModule.getTableName());
        }
    }

    @Override
    public int deleteModuleById(Long moduleId) {
        deleteDefaultModuleCache(moduleId);
        return sysModuleMapper.deleteModuleById(moduleId);
    }

    /**
     * 检查模块名称是否唯一
     * @param module 功能模块
     * @return true：唯一 false：已存在
     */
    @Override
    public boolean checkModuleNameUnique(SysModule module) {
        Long moduleId = StringUtils.isNull(module.getModuleId()) ? -1L : module.getModuleId();
        SysModule info = sysModuleMapper.checkModuleNameExist(module.getModuleName(), module.getRoleId());
        if (StringUtils.isNotNull(info) && info.getModuleId().longValue() != moduleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 检查关联表名是否唯一
     * @param module 功能模块
     * @return true：唯一 false：已存在
     */
    @Override
    public boolean checkTableNameUnique(SysModule module) {
        Long moduleId = StringUtils.isNull(module.getModuleId()) ? -1L : module.getModuleId();
        SysModule info = sysModuleMapper.checkTableNameExist(module.getTableName(), module.getRoleId());
        if (StringUtils.isNotNull(info) && info.getModuleId().longValue() != moduleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public SysModule getDefaultModuleByModuleName(String menuName) {
        return sysModuleMapper.getDefaultModuleByModuleName(menuName);
    }
}